package com.safewind.wx.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Strings;
import com.safewind.wx.constant.ErrorMsgConstant;

public class HttpUtil {
    private static final Logger logger = LoggerFactory.getLogger(HttpUtil.class);

    public static String getMethod(Map<String, String> header, String requestUrl, String charset) {
        if (Strings.isNullOrEmpty(requestUrl))
            return null;
        HttpClient httpclient = new HttpClient();
        GetMethod getMethod = new GetMethod(requestUrl);
        if (header != null) {
            for (Map.Entry<String, String> map : header.entrySet()) {
                getMethod.setRequestHeader(map.getKey(), map.getValue());
            }
        }
        StringBuilder httpResult = new StringBuilder();
        try {
            int statusCode = httpclient.executeMethod(getMethod);
            if (statusCode != HttpStatus.SC_OK) {
                throw new RuntimeException(ErrorMsgConstant.HTTP_REQUEST_FAIL);
            }
            InputStream responseBody = getMethod.getResponseBodyAsStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(responseBody, charset == null ? "utf-8"
                    : charset));
            String line = reader.readLine();
            while (line != null) {
                httpResult.append(line);
                line = reader.readLine();
            }
        } catch (HttpException e) {
            logger.error("HttpUtil --getMethod httpException :{}", e);
            throw new RuntimeException(ErrorMsgConstant.HTTP_REQUEST_EXCEPTION);
        } catch (IOException e) {
            logger.error("HttpUtil --getMethod ioException :{}", e);
            throw new RuntimeException(ErrorMsgConstant.READ_EXCEPTION);
        } finally {
            getMethod.releaseConnection();
        }
        return httpResult.toString();
    }

    /**
     * 发起https请求并获取结果
     *
     * @param requestUrl
     *            请求地址
     * @param requestMethod
     *            请求方式（GET、POST）
     * @param outputStr
     *            提交的数据
     * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
     */
    public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) {
        JSONObject jsonObject = null;
        StringBuffer buffer = new StringBuffer();
        try {
            // 创建SSLContext对象，并使用我们指定的信任管理器初始化
            TrustManager[] tm = { new MyX509TrustManager() };
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 从上述SSLContext对象中得到SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();

            URL url = new URL(requestUrl);
            HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
            httpUrlConn.setSSLSocketFactory(ssf);

            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);
            // 设置请求方式（GET/POST）
            httpUrlConn.setRequestMethod(requestMethod);

            if ("GET".equalsIgnoreCase(requestMethod))
                httpUrlConn.connect();

            // 当有数据需要提交时
            if (null != outputStr) {
                OutputStream outputStream = httpUrlConn.getOutputStream();
                // 注意编码格式，防止中文乱码
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }

            // 将返回的输入流转换成字符串
            InputStream inputStream = httpUrlConn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            bufferedReader.close();
            inputStreamReader.close();
            // 释放资源
            inputStream.close();
            inputStream = null;
            httpUrlConn.disconnect();
            jsonObject = JSON.parseObject(buffer.toString());
        } catch (ConnectException ce) {
            logger.error("server connection timed out.");
        } catch (Exception e) {
            logger.error("https request error:{}", e);
        }
        return jsonObject;
    }

    /**
     * 发起http请求并获取结果(POST)
     *
     * @param url
     *            请求地址
     * @param param
     *            提交的数据
     * @return String
     */
    public static String httpRequest(String url, NameValuePair[] param) {
        HttpClient client = new HttpClient();
        HttpMethod method = new PostMethod(url);
        String result = null;
        try {
            method.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
            method.setQueryString(param);
            client.executeMethod(method);
            result = method.getResponseBodyAsString();
        } catch (Exception e) {
            logger.error("server connection timed out.(Http,POST)");
        } finally {
            // 释放连接
            method.releaseConnection();
        }
        return result;
    }

    public static void httpRequest(String url, byte[] b) {
        URL u = null;
        HttpURLConnection con = null;
        try {
            u = new URL(url);
            con = (HttpURLConnection) u.openConnection();
            con.setRequestMethod("POST");
            con.setDoOutput(true);
            con.setDoInput(true);
            con.setUseCaches(false);
            con.setReadTimeout(30000);
            con.setRequestProperty("Content-Type", "binary/octet-stream");
            OutputStream outStream = con.getOutputStream();
            outStream.write(b);
            outStream.flush();
            outStream.close();
            con.connect();
            con.getInputStream();
        } catch (Exception e) {
        } finally {
            if (con != null) {
                con.disconnect();
            }
        }
    }
}
